<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');

if (! class_exists('PrunusRelation')) {
  class PrunusRelation extends Model {
    protected $tableName;
    protected $idColumnName;
    protected $aliveColumnName;
    protected $foreignKeyColumnName;
    protected $leftTable;
    protected $columns;
    protected $insertableRecordIdColumnName = 'id';
    protected $insertableRecordValueColumnName = 'value';
    protected $ci;

    //flags:
    // l  list
    // i  insert field

    public function __construct($tableName, $idColumnName, $aliveColumnName, $foreignKeyColumnName, $leftTableObject, $columns) {
      parent::__construct();
      $this->ci =& get_instance();
      $this->tableName = $tableName;
      $this->idColumnName = $idColumnName;
      $this->aliveColumnName = $aliveColumnName;
      $this->foreignKeyColumnName = $foreignKeyColumnName;
      $this->leftTable = $leftTableObject;
      $this->columns = $columns;
    }
    
    public function getIdColumn()                 { return ($this->idColumnName); }
    public function getInsertableRecordIdColumnName()   { return ($this->insertableRecordIdColumnName); }
    public function getInsertableRecordValueColumnName() { return ($this->insertableRecordValueColumnName); }
 
    public function countRecords($leftId = null, $alive = 1, $filters = null, $inlist = null) {
      if ($leftId !== null) {
        if ($filters == null) $filters = array();
        if (! is_numeric($leftId)) {
          $this->ci->db->where($this->leftTable->getSafeUrlColumn(), $leftId);
        } elseif (is_numeric($leftId))  {
          $this->ci->db->where($this->leftTable->getIdColumn(), (int) $leftId);
        }
      }
      $result = $this->_listRecords( TRUE, $alive, $filters, $inlist )->row_array();
      return (array_pop($result));
    }
    
    public function listRecords($leftId = null, $alive = 1, $filters = null, $inlist = null, $offset = null, $limit = null, $order = null) {
      if ($leftId !== null) {
        if ($filters == null) $filters = array();
        if (! is_numeric($leftId)) {
          $this->ci->db->where($this->leftTable->getSafeUrlColumn(), $leftId);
        } elseif (is_numeric($leftId))  {
          $this->ci->db->where($this->leftTable->getIdColumn(), (int) $leftId);
        }
      }
      return $this->_listRecords( FALSE, $alive, $filters, $inlist, $offset, $limit, $order );
    }
    
    private function _listRecords($count, $alive, $leftInlist, $rightInlist, $offset = null, $limit = null, $order = null) {
      if ($count) {
        $this->ci->db->select('count(0) ', FALSE);
      } else {
        $this->ci->db->select($this->idColumnName);
        foreach ($this->columns as $columnName=>$columnInfo) if (strpos($columnInfo['flags'],'l')!==FALSE) $this->ci->db->select($columnName);
      }
      
      $this->ci->db->from($this->leftTable->getTableName());
      $this->ci->db->join($this->tableName,  $this->foreignKeyColumnName . '=' . $this->leftTable->getIdColumn() );
      foreach ($this->columns as $colName=>$column) {
        if (isset($column['parent'])) {
          $this->ci->db->join($column['parent']['tableName'],  $column['parent']['idColumnName']. '=' . $colName, 'left');
          if (! $count) $this->ci->db->select($column['parent']['nameColumnName']);
        }
      }

      if ($leftInlist !== null) foreach ($leftInlist as $field=>$list) $this->db->where_in($field, $list);
      if ($rightInlist !== null) foreach ($rightInlist as $field=>$list) $this->db->where_in($field, $list);


      if ( ! $count) {
        if ($order !== null) foreach ($order as $field=>$value) $this->ci->db->order_by($field,$value);
        if ($offset !== null) $this->ci->db->limit($limit,$offset);
      }
      return ($this->ci->db->get());
    }
    
    
    public function insertRecord($foreignKeyId, $data = null, $dataNonEscaped = null) {
      $this->ci->db->set($this->foreignKeyColumnName, $foreignKeyId);
      if ($data !== null) foreach($data as $column=>$value) $this->ci->db->set($column, $value);
      if ($dataNonEscaped !== null) foreach($dataNonEscaped as $column=>$value) $this->ci->db->set($column, $value, FALSE);
      foreach ($this->columns as $columnName=>$columnInfo) if (array_key_exists('value', $columnInfo)) $this->ci->db->set($columnName, $columnInfo['value']);
      $this->ci->db->insert($this->tableName);
      return ($this->ci->db->insert_id());    
    }

    public function killRecord($id) {
      $this->ci->db->where($this->idColumnName, $id);
      return ($this->ci->db->delete($this->tableName));
    }

    public function getInsertColumns() { //solo para ayudar en el insert
      $out = array();                                                                                                               
      foreach ($this->columns as $columnName=>$columnInfo) if ((strpos($columnInfo['flags'],'i')!==FALSE) && ($columnName != $this->foreignKeyColumnName)) $out[] = $columnName; //no incluyo la foreign key
      return ($out);
    }
    
    public function listInsertableRecords($fieldName, $leftId, $alive = null) {
      $sql = "";
      $ok = FALSE;
      if (array_key_exists($fieldName, $this->columns)) {
        if (array_key_exists('parent', $this->columns[$fieldName])) {
          if (array_key_exists('duplicates', $this->columns[$fieldName]['parent'])) $duplicates = $this->columns[$fieldName]['parent']['duplicates']; else $duplicates = FALSE;
          if (array_key_exists('optionalValue', $this->columns[$fieldName]['parent'])) $optional = $this->columns[$fieldName]['parent']['optionalValue']; else $optional = FALSE;
          $ok = TRUE;
        }
      }
      
      if ($ok) {
        if ($duplicates) {
          if ($optional !== FALSE) $sql .= "SELECT " . $optional . " " . $this->insertableRecordIdColumnName . ", '' " . $this->insertableRecordValueColumnName . " UNION";
          $sql .= " SELECT " . $this->columns[$fieldName]['parent']['idColumnName'] . " " . $this->insertableRecordIdColumnName . "," . $this->columns[$fieldName]['parent']['nameColumnName'] . " " . $this->insertableRecordValueColumnName;
          $sql .= " FROM " . $this->columns[$fieldName]['parent']['tableName'];
          if ($alive !== null) $sql .= " AND " . $this->columns[$fieldName]['parent']['aliveColumnName'] . "=" . $alive;
          return ($this->ci->db->query($sql));
        } else {
          if ($optional !== FALSE) $sql .= "SELECT " . $optional . " " . $this->insertableRecordIdColumnName . ", '' " . $this->insertableRecordValueColumnName . " UNION";
          $sql .= " SELECT " . $this->columns[$fieldName]['parent']['idColumnName'] . " " . $this->insertableRecordIdColumnName . "," . $this->columns[$fieldName]['parent']['nameColumnName'] . " " . $this->insertableRecordValueColumnName;
          $sql .= " FROM " . $this->columns[$fieldName]['parent']['tableName'];
          $sql .= " WHERE " . $this->columns[$fieldName]['parent']['idColumnName'] . " not in (select " . $fieldName . " from " . $this->tableName . " where " . $this->foreignKeyColumnName . "=" . $leftId . ")";
          if ($alive !== null) $sql .= " AND " . $this->columns[$fieldName]['parent']['aliveColumnName'] . "=" . $alive;
          return ($this->ci->db->query($sql));
        }
      } else {
        return (array());
      }
    }

    
  }
}
 
